import { limitRange } from "../utils";
import { operateType } from "@/enum";

const MIN_SCALE = 1;
export default function (
    { axisRef, axisBoxRef, boxWrapperRef },
    scaleGroup,
    translateGroup,
    config,
    status
) {
    const scaleStack = [];
    watch(
        () => axisBoxRef.value,
        (val) => {
            val.addEventListener("wheel", (event) => {
                status.value = operateType.ZOOM;
                const { wheelDeltaY, clientX } = event;
                const { offsetLeft, clientLeft } = val;

                let scale = getScale(wheelDeltaY);
                let deltaX = 0;
                if (translateGroup.value.startX) {
                    deltaX =
                        translateGroup.value.startX -
                        translateGroup.value.offset;
                }
                let origin =
                    clientX -
                    offsetLeft -
                    clientLeft -
                    axisRef.value.offsetLeft;
                if (wheelDeltaY > 0) {
                    if (origin !== scaleGroup.value.origin) {
                        scaleStack.push({
                            scale: scaleGroup.value.scale,
                            origin,
                        });
                    }
                } else {
                    const stackTop = scaleStack[scaleStack.length - 1];
                    if (!stackTop) return;
                    origin = stackTop.origin;
                    if (stackTop.scale >= scale) {
                        scaleStack.pop();
                    }
                }
                const scaleStep = scale / scaleGroup.value.scale;
                let lastOffset =
                    scaleGroup.value.offset +
                    (deltaX * scale) / translateGroup.value.scale;
                let offset =
                    lastOffset * scaleStep +
                    (scaleStep - 1) * (origin - deltaX);

                if (scale === 1) {
                    offset = 0;
                }

                boxWrapperRef.value.style.width = scale * 100 + "%";
                boxWrapperRef.value.style.left = -offset + "px";

                scaleGroup.value = {
                    scale,
                    origin,
                    offset,
                };
                translateGroup.value = {
                    offset: null,
                    startX: null,
                    scale: 1,
                };
                requestAnimationFrame(() => {
                    status.value = operateType.DEFAULT;
                });
            });
        }
    );

    function getScale(wheelDeltaY) {
        return limitRange(
            MIN_SCALE,
            config.scaleMax,
            wheelDeltaY > 0
                ? scaleGroup.value.scale + config.scaleStep
                : scaleGroup.value.scale - config.scaleStep
        );
    }
}
